using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Printing;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace OpenRPOS
{

    public partial class MainPage : UserControl
    {
        Dictionary<Button, ServiceReferenceOpenRPOS.MenuItem> dictButtonMenuItems = new Dictionary<Button, ServiceReferenceOpenRPOS.MenuItem>();
        Dictionary<string, ServiceReferenceOpenRPOS.MenuItem> dictOptionItems = new Dictionary<string, ServiceReferenceOpenRPOS.MenuItem>();
        ServiceReferenceOpenRPOS.MenuItemOptionGroup currentMenuItemOptionGroup;
        OptionDialog currentOptionDialog;
        ObservableCollection<OrderData> orderDisplayDataSource = new ObservableCollection<OrderData>();
        List<OrderData> orderDataList=new List<OrderData>();
        List<int> orderSummaryIDList = new List<int>();
        OrderData currentOrderData;
        ServiceReferenceOpenRPOS.OrderSummary currentOrderSummary = new ServiceReferenceOpenRPOS.OrderSummary();
        int iCurrentOptionGroupIndex, iCurrentMenuItemID;
        bool bExclusive;
        decimal decCurrentTotal = 0;

        public MainPage()
        {
            InitializeComponent();
            App.Current.Host.Content.FullScreenOptions = FullScreenOptions.StaysFullScreenWhenUnfocused;
        }

        public async Task<Boolean> init()
        {
            double dblTabWidth = tcMenuCategories.Width - Globals.k_dbl_button_spacing,
                dblTabHeight = tcMenuCategories.Height - Globals.k_dbl_tab_height, dblButtonWidth, dblButtonHeight;
            TextBlock buttonTextBlock;

            try
            {
                // Load display information from the database
                await Globals.db.GetMenuCategoryObjects("Active=1 and Visible=1 order by Precedence");
                await Globals.db.GetMenuItemObjects("Active=1 and Enabled=1 order by FullName");
                await Globals.db.GetMenuItemOptionGroupObjects("1=1 order by MenuItemID,Precedence");
                await Globals.db.GetMenuOptionObjects("");
                await Globals.db.GetOptionGroupObjects("Active=1");
                await Globals.db.GetLoginObjects("");
                await getOpenOrders();
                dgCurrentOrder.ItemsSource = orderDisplayDataSource;
                dictButtonMenuItems.Clear();
                currentOrderSummary.col_Status = Globals.k_int_status_open;
                // Populate the tab control with menu items
                tcMenuCategories.Items.Clear();
                // Check all menu categories...
                foreach (ServiceReferenceOpenRPOS.MenuCategory mc in Globals.db.MenuCategoryRecords)
                {
                    // Add tabs for each menu category
                    TabItem ti = new TabItem();
                    ti.Header = mc.col_Name;
                    Grid g = new Grid();
                    var count = Globals.db.MenuItemRecords.Where(x => x.col_MenuCategoryID == mc.col_ID).Count();
                    // Add buttons for items in each menu category
                    if (count > 0)
                    {
                        int hbuttons = (int)Math.Sqrt(count);
                        int vbuttons = count / hbuttons;
                        int hcnt=0, vcnt=0, cnt=0;
                        vbuttons = (count > (hbuttons * vbuttons)) ? vbuttons + 1 : vbuttons;
                        dblButtonWidth = (dblTabWidth / hbuttons) - (Globals.k_dbl_button_spacing+1);
                        dblButtonHeight = (dblTabHeight / vbuttons) - (Globals.k_dbl_button_spacing);
                        foreach (ServiceReferenceOpenRPOS.MenuItem mi in Globals.db.MenuItemRecords.Where(x => x.col_MenuCategoryID == mc.col_ID))
                        {
                            Button btn = new Button();
                            // Size and position buttons such that they fit evenly on the screen
                            hcnt = cnt % hbuttons;
                            vcnt = cnt / hbuttons;
                            buttonTextBlock = new TextBlock();
                            buttonTextBlock.TextWrapping = TextWrapping.Wrap;
                            buttonTextBlock.TextAlignment = TextAlignment.Center;
                            buttonTextBlock.Text = mi.col_FullName;
                            btn.Content = buttonTextBlock;
                            btn.Margin = new Thickness(hcnt * dblButtonWidth + ((hcnt + 1) * Globals.k_dbl_button_spacing), vcnt * dblButtonHeight + (vcnt * Globals.k_dbl_button_spacing), 0, 0);
                            btn.Width = dblButtonWidth;
                            btn.Height = dblButtonHeight;
                            btn.HorizontalAlignment = HorizontalAlignment.Left;
                            btn.VerticalAlignment = VerticalAlignment.Top;
                            dictButtonMenuItems[btn] = mi;
                            btn.Click += new RoutedEventHandler(OnMenuItemButtonClick);
                            g.Children.Add(btn);
                            cnt++;
                        }
                    }
                    ti.Content = g;
                    tcMenuCategories.Items.Add(ti);
                }
                
            }
            catch (Exception ex)
            {
                // Pass the exception back to the caller
                throw (ex);
            }
            Globals.bInit = true;
            return true;
        }

        void OnMenuItemButtonClick(object sender,EventArgs e)
        {
            Button btn = (Button)sender;
            // Add item to order
            OrderData od = new OrderData();
            od.MenuItemID = dictButtonMenuItems[btn].col_ID;
            od.MenuItemName = dictButtonMenuItems[btn].col_FullName;
            od.DisplayPrice = dictButtonMenuItems[btn].col_Price.ToString("N");
            od.Price = dictButtonMenuItems[btn].col_Price;
            decCurrentTotal += od.Price;
            lblTotal.Content = decCurrentTotal.ToString("N");
            orderDisplayDataSource.Add(od);
            dgCurrentOrder.ScrollIntoView(od, null);
            dgCurrentOrder.Focus();
            btnSend.IsEnabled = true;
            btnClose.IsEnabled = true;
            btnNew.IsEnabled = true;
            // Determine if any option groups exist...
            if (Globals.db.MenuItemOptionGroupRecords.Where(x => x.col_MenuItemID == dictButtonMenuItems[btn].col_ID).Count() > 0)
            {
                iCurrentOptionGroupIndex = 0;
                iCurrentMenuItemID = dictButtonMenuItems[btn].col_ID;
                currentMenuItemOptionGroup = Globals.db.MenuItemOptionGroupRecords.Where(x => x.col_MenuItemID == iCurrentMenuItemID).ElementAt(iCurrentOptionGroupIndex++);
                od.Options = new List<OrderData>();
                od.Options.Clear();
                currentOrderData = od;
                createOptionGroupDialog();
            }
        }

        void createOptionGroupDialog()
        {
            OptionDialog od = new OptionDialog();
            Dictionary<string, int> dictMenuItems = new Dictionary<string, int>();
            ServiceReferenceOpenRPOS.OptionGroup og = Globals.db.OptionGroupRecords.Where(x => x.col_ID == currentMenuItemOptionGroup.col_OptionGroupID).First();
            dictOptionItems.Clear();
            // Determine the number of options
            foreach (ServiceReferenceOpenRPOS.MenuOption mo in Globals.db.MenuOptionRecords.Where(x => x.col_OptionGroupID == currentMenuItemOptionGroup.col_OptionGroupID))
            {
                if (Globals.db.MenuItemRecords.Where(x => x.col_ID == mo.col_MenuItemID).Count() > 0)
                {
                    ServiceReferenceOpenRPOS.MenuItem mi = Globals.db.MenuItemRecords.Where(x => x.col_ID == mo.col_MenuItemID).First();
                    dictMenuItems.Add(mi.col_FullName, mi.col_ID);
                    dictOptionItems.Add(mi.col_FullName, mi);
                }
            }
            // Display options in alphabetical order
            var list = dictMenuItems.Keys.ToList();
            list.Sort();
            int cnt = 0;
            bExclusive = og.col_Exclusive;
            // Iterate over the options in the group
            foreach (var key in list)
            {
                // Double the size of the options for easier selection
                ScaleTransform st = new ScaleTransform();
                st.ScaleX = 2;
                st.ScaleY = 2;
                // Use radio buttons for an exclusive option group
                if (bExclusive)
                {
                    RadioButton rb = new RadioButton();
                    rb.Content = key;
                    rb.Height = Globals.k_dbl_radio_button_height;
                    if (cnt == 0) rb.IsChecked = true;
                    rb.Margin = new Thickness(Globals.k_dbl_button_spacing * 2, cnt++ * rb.Height * 2, 0, 0);
                    rb.Padding = new Thickness(Globals.k_dbl_option_padding, Globals.k_dbl_option_padding, 0, 0);
                    rb.HorizontalAlignment = HorizontalAlignment.Left;
                    rb.VerticalAlignment = VerticalAlignment.Top;
                    rb.RenderTransform = st;
                    od.LayoutRoot.Children.Add(rb);
                }
                else // Used check-box for non-exclusive (multiple options allowed) group
                {
                    CheckBox cb = new CheckBox();
                    cb.Content = key;
                    cb.Padding = new Thickness(Globals.k_dbl_option_padding, -1 * Globals.k_dbl_option_padding, 0, 0);
                    cb.Margin = new Thickness(Globals.k_dbl_button_spacing, cnt++ * Globals.k_dbl_checkbox_height * 2, 0, 0);
                    cb.RenderTransform = st;
                    od.LayoutRoot.Children.Add(cb);
                }
            }
            // Size the dialog
            od.Width = Globals.k_dbl_option_group_width * 2.5;
            od.Height = cnt * (og.col_Exclusive ? Globals.k_dbl_radio_button_height : Globals.k_dbl_checkbox_height) * 2 + Globals.k_dbl_option_group_min_height;
            od.btnOK.Click += new RoutedEventHandler(OnOptionDialogOKButtonClick);
            currentOptionDialog = od;
            od.Show();
        }

        void OnOptionDialogOKButtonClick(object sender, EventArgs e)
        {
            currentOptionDialog.DialogResult = true;
            // Add selected options...
            if (bExclusive)
            {
                // Identify the selected item
                foreach (UIElement uie in currentOptionDialog.LayoutRoot.Children)
                {
                    if (uie.GetType().ToString().Contains("RadioButton"))
                    {
                        RadioButton rb = (RadioButton)uie;
                        if (rb.IsChecked == true) // Selected
                        {
                            // Add item to order
                            OrderData od = new OrderData();
                            od.MenuItemID = dictOptionItems[rb.Content.ToString()].col_ID;
                            od.MenuItemName = "  " + dictOptionItems[rb.Content.ToString()].col_FullName;
                            od.DisplayPrice = (dictOptionItems[rb.Content.ToString()].col_Price>0?dictOptionItems[rb.Content.ToString()].col_Price.ToString("N"):"");
                            od.Price = dictOptionItems[rb.Content.ToString()].col_Price;
                            od.Exclusive = true;
                            od.Parent = currentOrderData;
                            currentOrderData.Options.Add(od);
                            decCurrentTotal += od.Price;
                            lblTotal.Content = decCurrentTotal.ToString("N");
                            orderDisplayDataSource.Add(od);
                            dgCurrentOrder.ScrollIntoView(od, null);
                            dgCurrentOrder.Focus();
                        }
                    }
                }
            }
            else
            {
                // Identify the selected item
                foreach (UIElement uie in currentOptionDialog.LayoutRoot.Children)
                {
                    if (uie.GetType().ToString().Contains("CheckBox"))
                    {
                        CheckBox cb = (CheckBox)uie;
                        if (cb.IsChecked == true) // Selected
                        {
                            // Add item to order
                            OrderData od = new OrderData();
                            od.MenuItemID = dictOptionItems[cb.Content.ToString()].col_ID;
                            od.MenuItemName = "  " + dictOptionItems[cb.Content.ToString()].col_FullName;
                            od.DisplayPrice = (dictOptionItems[cb.Content.ToString()].col_Price > 0 ? dictOptionItems[cb.Content.ToString()].col_Price.ToString("N") : "");
                            od.Price = dictOptionItems[cb.Content.ToString()].col_Price;
                            od.Exclusive = false;
                            od.Parent = currentOrderData;
                            decCurrentTotal += od.Price;
                            lblTotal.Content = decCurrentTotal.ToString("N");
                            currentOrderData.Options.Add(od);
                            orderDisplayDataSource.Add(od);
                            dgCurrentOrder.ScrollIntoView(od, null);
                            dgCurrentOrder.Focus();
                        }
                    }
                }
            }
            // Determine if another option dialog needs to be displayed
            if (Globals.db.MenuItemOptionGroupRecords.Where(x => x.col_MenuItemID == iCurrentMenuItemID).Count() > iCurrentOptionGroupIndex)
            {
                // Display the next option group
                currentMenuItemOptionGroup = Globals.db.MenuItemOptionGroupRecords.Where(x => x.col_MenuItemID == iCurrentMenuItemID).ElementAt(iCurrentOptionGroupIndex++);
                createOptionGroupDialog();
            }
        }

        private async void btnLogOut_Click(object sender, RoutedEventArgs e)
        {
            // Ensure that the user actually wants to logout
            if (MessageBox.Show("Are you sure you want to logout?", "Confirm", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                // Send the current check (if needed)
                if (btnSend.IsEnabled)
                    await sendOrder();
                // Clear the current check
                btnClose.IsEnabled = false;
                btnNew.IsEnabled = false;
                orderDisplayDataSource.Clear();
                currentOrderSummary = new ServiceReferenceOpenRPOS.OrderSummary();
                await getOpenOrders();
                // Return to the login screen
                Globals.root.Content = Globals.login;
                if (tcMenuCategories.Items.Count > 0) tcMenuCategories.SelectedIndex = 0;
                nudTable.Value = 0;
            }
        }

        private void recalculateTotal()
        {
            decCurrentTotal = 0;
            foreach (OrderData od in dgCurrentOrder.ItemsSource)
            {
                decCurrentTotal += od.Price;
            }
            lblTotal.Content = decCurrentTotal.ToString("N");
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            // Remove selected items from the list            
            foreach (OrderData od in orderDisplayDataSource)
            {
                if (!od.Exclusive)
                    if (dgCurrentOrder.SelectedItems.Contains(od))
                        orderDataList.Add(od);
            }
            foreach (OrderData od in orderDataList)
            {
                if (od.Options != null)
                    foreach (OrderData odOption in od.Options)
                    {
                        // Remove the option from the list
                        orderDisplayDataSource.Remove(odOption);
                    }
                // Don't remove exclusive options...
                if (!od.Exclusive)
                {
                    // Clear the option from the parent, if one exists
                    if (od.Parent != null)
                        od.Parent.Options.Remove(od);
                    orderDisplayDataSource.Remove(od);
                }
            }
            orderDataList.Clear();
            dgCurrentOrder.SelectedItems.Clear();
            recalculateTotal();
            btnSend.IsEnabled = true;
        }

        private void dgCurrentOrder_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            List<OrderData> tmpOrderDataList = new List<OrderData>();
            if (dgCurrentOrder.SelectedItems.Count > 0)
            {
                btnDelete.IsEnabled = true;
                foreach (OrderData od in dgCurrentOrder.SelectedItems)
                    if (od.Exclusive)
                        tmpOrderDataList.Add(od);
            }
            else btnDelete.IsEnabled = false;
            // Remove exclusive options from the selection list...
            foreach (OrderData od in tmpOrderDataList)
            {
                dgCurrentOrder.SelectedItems.Remove(od);
            }
        }

        private async Task<Boolean> sendOrder()
        {
            btnSend.IsEnabled = false;
            // Send the order
            Globals.showWaitCursor(true);

            // Determine if this is a new order
            if (currentOrderSummary.col_Status == Globals.k_int_status_open)
            {
                currentOrderSummary.bFilterStatus = true;
                currentOrderSummary.bFilterCreated = true;
                currentOrderSummary.bFilterLoginID = true;
                currentOrderSummary.col_LoginID = Globals.currentLogin.col_ID;
                currentOrderSummary.col_Created = DateTime.Now;
                currentOrderSummary.col_Status = Globals.k_int_status_sent;
            }
            currentOrderSummary.bFilterTableNumber = true;
            currentOrderSummary.bFilterSubtotal = true;
            currentOrderSummary.col_TableNumber = (int)nudTable.Value;
            currentOrderSummary.col_Subtotal = decCurrentTotal;
            Globals.db.OrderDetailRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail>();
            Globals.db.OrderOptionRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderOption>();
            int iOrderDetailID = 0;
            // Traverse the list of order items and send those to the database
            foreach (OrderData orderData in orderDisplayDataSource)
            {
                if (orderData.Parent == null)
                {
                    // Add a new order detail item
                    ServiceReferenceOpenRPOS.OrderDetail orderDetail = new ServiceReferenceOpenRPOS.OrderDetail();
                    orderDetail.bFilterOrderSummaryID = true;
                    orderDetail.bFilterMenuItemID = true;
                    orderDetail.bFilterPrice = true;
                    orderDetail.col_OrderSummaryID = currentOrderSummary.col_ID;
                    orderDetail.col_MenuItemID = orderData.MenuItemID;
                    orderDetail.col_Price = orderData.Price;
                    orderDetail.col_ID = iOrderDetailID++;
                    Globals.db.OrderDetailRecords.Add(orderDetail);
                    // Check for options
                    if (orderData.Options != null)
                        foreach (OrderData odOption in orderData.Options)
                        {
                            ServiceReferenceOpenRPOS.OrderOption orderOption = new ServiceReferenceOpenRPOS.OrderOption();
                            orderOption.bFilterMenuItemID = true;
                            orderOption.bFilterOrderDetailID = true;
                            orderOption.bFilterExclusive = true;
                            orderOption.bFilterPrice = true;
                            orderOption.col_Exclusive = odOption.Exclusive;
                            orderOption.col_MenuItemID = odOption.MenuItemID;
                            orderOption.col_OrderDetailID = orderDetail.col_ID;
                            orderOption.col_Price = odOption.Price;
                            Globals.db.OrderOptionRecords.Add(orderOption);
                        }
                }
            }
            try
            {
                int iOrderSummaryID = await Globals.db.SendOrder(currentOrderSummary, Globals.db.OrderDetailRecords, Globals.db.OrderOptionRecords);
                if (currentOrderSummary.col_ID == 0) currentOrderSummary.col_ID = iOrderSummaryID;
            }
            catch (System.Net.WebException ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Response.ToString());
            }

            Globals.showWaitCursor(false);
            return true;
        }

        public async Task<Boolean> getOpenOrders()
        {
            // Return any non-closed orders
            string filter = "status!=" + Globals.k_int_status_closed.ToString();
            // Only Managers have the ability to view/edit other checks...
            if (!Globals.currentLogin.col_Manager)
                filter += " and LoginID=" + Globals.currentLogin.col_ID.ToString();
            await Globals.db.GetOrderSummaryObjects(filter);
            // Add open orders to the combo box
            cmbOpenOrders.Items.Clear();
            orderSummaryIDList.Clear();
            foreach (ServiceReferenceOpenRPOS.OrderSummary os in Globals.db.OrderSummaryRecords)
            {
                string strComboBoxItemText = Globals.db.LoginRecords.Where(x => x.col_ID == os.col_LoginID).First().col_DisplayName;
                strComboBoxItemText += " - Table " + os.col_TableNumber.ToString()+", # "+(os.col_ID%100).ToString();
                cmbOpenOrders.Items.Add(strComboBoxItemText);
                orderSummaryIDList.Add(os.col_ID);
            }
            return true;
        }

        private async Task<Boolean> closeCurrentOrder()
        {
            // Disable the "close" button
            btnClose.IsEnabled = false;
            // Disable the "new" button
            btnNew.IsEnabled = false;
            // Close the check
            currentOrderSummary.bFilterTableNumber = true;
            currentOrderSummary.bFilterStatus = true;
            currentOrderSummary.bFilterSubtotal = true;
            currentOrderSummary.col_Subtotal = decCurrentTotal;
            currentOrderSummary.col_Status = Globals.k_int_status_closed;
            currentOrderSummary.col_TableNumber = (int)nudTable.Value;
            await Globals.db.UpdateOrderSummaryObject(currentOrderSummary);
            orderDisplayDataSource.Clear();
            currentOrderSummary = new ServiceReferenceOpenRPOS.OrderSummary();
            recalculateTotal();
            await getOpenOrders();
            if(tcMenuCategories.Items.Count>0) tcMenuCategories.SelectedIndex = 0;
            nudTable.Value = 0;
            return true;
        }

        private async void btnSend_Click(object sender, RoutedEventArgs e)
        {
            await sendOrder();
        }

        private async void btnClose_Click(object sender, RoutedEventArgs e)
        {
            // Send the check (if needed)
            if (btnSend.IsEnabled)
                await sendOrder();
            // Clear out the current order information
            await closeCurrentOrder();
        }

        private async void btnNew_Click(object sender, RoutedEventArgs e)
        {
            // Send the check (if needed)
            if (btnSend.IsEnabled)
                await sendOrder();
            // Disable the "close" button
            btnClose.IsEnabled = false;
            // Disable the "new" button
            btnNew.IsEnabled = false;
            // Clear out the current order information
            orderDisplayDataSource.Clear();
            currentOrderSummary = new ServiceReferenceOpenRPOS.OrderSummary();
            recalculateTotal();
            await getOpenOrders();
            if (tcMenuCategories.Items.Count > 0) tcMenuCategories.SelectedIndex = 0;
            nudTable.Value = 0;
        }

        private async void cmbOpenOrders_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Send the check (if needed)
            if (btnSend.IsEnabled)
                await sendOrder();
            Globals.showWaitCursor(true);
            // Disable the "close" button
            btnClose.IsEnabled = false;
            // Clear out the current order information
            orderDisplayDataSource.Clear();
            if (cmbOpenOrders.SelectedIndex >= 0)
            {
                // Initialize the running total...
                decCurrentTotal = 0;
                // Enable the "new" button
                btnNew.IsEnabled = true;
                // Enable the "close" button
                btnClose.IsEnabled = true;
                // Get the selected order
                await Globals.db.GetOrderSummaryObjects("ID=" + orderSummaryIDList[cmbOpenOrders.SelectedIndex]);
                currentOrderSummary = Globals.db.OrderSummaryRecords.First();
                nudTable.Value = (double)currentOrderSummary.col_TableNumber;
                currentOrderSummary.bFilterTableNumber = true;
                await Globals.db.UpdateOrderSummaryObject(currentOrderSummary);
                await Globals.db.GetOrderDetailObjects("OrderSummaryID=" + currentOrderSummary.col_ID.ToString() + " order by ID");
                if (Globals.db.OrderDetailRecords.Count() > 0)
                {
                    string strOrderDetailIDs = "(";
                    foreach (ServiceReferenceOpenRPOS.OrderDetail od in Globals.db.OrderDetailRecords)
                    {
                        strOrderDetailIDs += od.col_ID.ToString() + ",";
                    }
                    strOrderDetailIDs = strOrderDetailIDs.Substring(0, strOrderDetailIDs.Length - 1) + ")";
                    await Globals.db.GetOrderOptionObjects("OrderDetailID in " + strOrderDetailIDs + " order by ID");
                    // Add item to order
                    foreach (ServiceReferenceOpenRPOS.OrderDetail od in Globals.db.OrderDetailRecords)
                    {
                        // Add the order item
                        OrderData orderData = new OrderData();
                        ServiceReferenceOpenRPOS.MenuItem mi = Globals.db.MenuItemRecords.Where(x => x.col_ID == od.col_MenuItemID).First();
                        orderData.MenuItemID = mi.col_ID;
                        orderData.MenuItemName = mi.col_FullName;
                        orderData.DisplayPrice = mi.col_Price.ToString("N");
                        orderData.Price = mi.col_Price;
                        decCurrentTotal += orderData.Price;
                        lblTotal.Content = decCurrentTotal.ToString("N");
                        orderDisplayDataSource.Add(orderData);
                        dgCurrentOrder.ScrollIntoView(orderData, null);
                        dgCurrentOrder.Focus();
                        // Add options...
                        if (Globals.db.OrderOptionRecords.Where(x => x.col_OrderDetailID == od.col_ID).Count() > 0)
                        {
                            orderData.Options = new List<OrderData>();
                            foreach (ServiceReferenceOpenRPOS.OrderOption oo in Globals.db.OrderOptionRecords.Where(x => x.col_OrderDetailID == od.col_ID))
                            {
                                OrderData orderOptionData = new OrderData();
                                ServiceReferenceOpenRPOS.MenuItem miOption = Globals.db.MenuItemRecords.Where(x => x.col_ID == oo.col_MenuItemID).First();
                                orderOptionData.MenuItemID = miOption.col_ID;
                                orderOptionData.MenuItemName = "  " + miOption.col_FullName;
                                orderOptionData.DisplayPrice = (miOption.col_Price > 0) ? miOption.col_Price.ToString("N") : "";
                                orderOptionData.Price = miOption.col_Price;
                                orderOptionData.Exclusive = oo.col_Exclusive;
                                orderData.Options.Add(orderOptionData);
                                orderOptionData.Parent = orderData;
                                decCurrentTotal += orderOptionData.Price;
                                orderDisplayDataSource.Add(orderOptionData);
                                dgCurrentOrder.ScrollIntoView(orderOptionData, null);
                                dgCurrentOrder.Focus();
                            }
                        }
                    }
                }
            }
            lblTotal.Content = decCurrentTotal.ToString("N");
            if (tcMenuCategories.Items.Count > 0) tcMenuCategories.SelectedIndex = 0;
            Globals.showWaitCursor(false);
        }

    }

    public class OrderData
    {
        public int MenuItemID { get; set; }
        public string MenuItemName { get; set; }
        public string DisplayPrice { get; set; }
        public decimal Price { get; set; }
        public bool Exclusive { get; set; }
        public List<OrderData> Options { get; set; }
        public OrderData Parent { get; set; }
    }
}